<!--
  This is THE board, which is running Firmata firmware. Tipically an Arduino or RPi-Pico
-->

<script type="text/html" data-template-name="arduino-board">
    <div class="form-row">
        <label for="node-config-input-name"><i class="fa fa-tag"></i> <span data-i18n="arduino.label.name"></span></label>
        <input type="text" id="node-config-input-name" style="width:60%;"/>
    </div>
    <div class="form-row">
        <label for="node-config-input-device"><i class="fa fa-random"></i> <span data-i18n="arduino.label.port"></span></label>
        <input type="text" id="node-config-input-device" style="width:60%;" data-i18n="[placeholder]arduino.placeholder.port"/>
        <a id="node-config-lookup-serial" class="red-ui-button"><i id="node-config-lookup-serial-icon" class="fa fa-search"></i></a>
        <div class="form-tips"><span data-i18n="[html]arduino.tip.port"></span></div>
    </div>
    <div class="form-row">
        <div class="form-tips"><span data-i18n="[html]arduino.tip.otherboards"></span></div>
    </div>
    <div class="form-row">
        <label for="node-config-input-samplingInt" style="width:150px;"><i class="fa fa-circle"></i> <span data-i18n="arduino.label.samplingInt"></span></label>
        <input type="number" id="node-config-input-samplingInt" style="width:20%;" data-i18n="[placeholder]arduino.placeholder.samplingInt" min=10 max=65500 /> mS
    </div>
    <div class="form-row">
		<label for="node-config-input-log2consol"><i class="icon-bookmark"></i>Log to console</label>
		<input type="checkbox" id="node-config-input-log2consol">
        <div class="form-tips"><span data-i18n="[html]arduino.tip.log2consol"></span></div>
	</div>
    <!-- arduino.tip.... strings are stored at: 35-arduino.json file -->
</script>

<script type="text/javascript">
    RED.nodes.registerType('arduino-board',{
        category: 'config',
        defaults: {
            device     : {value: ""   , required: true },
            name       : {value: ""   , required: false},
            samplingInt: {value: 250  , required: false}, // will read analog inputs 4x / sec by default. Can be 19-65500
            log2consol : {value: false, required: false}
        },
        label: function() {
            if (this.name !== "") return this.name
            else return this.device || "firmata-board-" + this.id; // (bad naming :-( ) device should be: "port"
        },
        oneditprepare: function() {
            try {
                $("#node-config-input-device").autocomplete( "destroy" ); // Remove auto-complete functionality from an <input>.
            } catch(err) { };

            $("#node-config-lookup-serial").click(async function() { // Board's serial port search function
                console.log("Serial Auto-search started.");
                $("#node-config-lookup-serial-icon").removeClass('fa-search').addClass('spinner');
                $("#node-config-lookup-serial").addClass('disabled');

                try {
                    $.getJSON('arduinoports', async function(data, data2) {
                        //console.log('Serial Auto-search found data: %o', data);
                        //console.log('Data2: %o', data2);

                        // UI Updates
                        $("#node-config-lookup-serial-icon").removeClass('spinner').addClass('fa-search');
                        $("#node-config-lookup-serial").removeClass('disabled');
                        // Ensure ports is an array (fallback to empty array)
                        ports = data || [];

                        $("#node-config-input-device").autocomplete({
                            source: ports,
                            minLength: 0,
                            close: function(event, ui) {
                                console.log("Serial Auto-search closing.");
                                $("#node-config-input-device").autocomplete("destroy");
                            }
                        }).autocomplete("search", "");
                    });
                } catch (error) {
                    console.error('Error fetching serial ports:', error);

                    // Reset UI on error
                    $("#node-config-lookup-serial-icon").removeClass('spinner').addClass('fa-search');
                    $("#node-config-lookup-serial").removeClass('disabled');
                }
            });
        }
    });
</script>


<!--
  In - node
-->
<script type="text/html" data-template-name="arduino in">
    <div class="form-row">
        <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="node-red:common.label.name"></span></label>
        <input type="text" id="node-input-name" data-i18n="[placeholder]node-red:common.label.name">
    </div>
    <div class="form-row">
        <label for="node-input-arduino"><i class="fa fa-tasks"></i> Arduino</label>
        <input type="text" id="node-input-arduino">
    </div>
    <div class="form-row">
        <label for="node-input-state"><i class="fa fa-wrench"></i> <span data-i18n="arduino.label.type"></span></label>
        <select type="text" id="node-input-state" style="width:200px;">
            <option value="INPUT" data-i18n="arduino.state.in.digital"></option>
            <option value="PULLUP" data-i18n="arduino.state.in.pullup"></option>
            <option value="ANALOG" data-i18n="arduino.state.in.analogue"></option>
            <option value="STRING" data-i18n="arduino.state.in.string"></option>
        </select>
    </div>
    <div class="form-row">
        <label for="node-input-pin"><i class="fa fa-circle"></i> <span data-i18n="arduino.label.pin"></span></label>
        <input type="number" min="0" max="99" id="node-input-pin" style="width:20%;" placeholder="2">
    </div>
    <div class="form-tips"><span data-i18n="[html]arduino.tip.pin"></span></div>
    <div class="form-tips"><span data-i18n="[html]arduino.tip.io"></span></div>
</script>

<script type="text/javascript">
    RED.nodes.registerType('arduino in',{
        category: 'Arduino',
        color:"#3fadb5",
        defaults: {
            name: {value:""},
            pin: {value:"",validate: function(v) {
                    var ct = $("#node-input-state").val() || this.state;
                    return ct === 'STRING' || (v !== '');
                }},
            state: {value:"INPUT",required:true},
            arduino: {type:"arduino-board"}
        },
        inputs:0,
        outputs:1,
        icon: "arduino.png",
        label: function() {
            if (this.state === "STRING") { return "String"; }
            let a = "";
            if (this.state === "ANALOG") { a = "A"; }
            return this.name || "Pin: " + a + this.pin;
        },
        labelStyle: function() {
            return this.name ? "node_label_italic":"";
        }
    });
</script>

<script type="text/x-red" data-help-name="arduino in">
	<p>This is a "Firmata protocol" based communication, between Node-RED and a connected (Arduino, ESP32, RPi-Pico, etc..) board(s), running firmata firmware. </p>
	<p>It is working with many boards, not just Arduino. </p>
	<p>This node's code is at: https://github.com/node-red/node-red-nodes/tree/master/hardware/Arduino </p>
	<p> </p>

	<h3>Settings:</h3>
	<p>[b]Arduino:[/b] You can create a new "board", or choose from previously created. That will represent the chip or board connected.</p>
	<p>On Unix/linux systems, it is recommended to choose the COM port at "by-serial", so it works always, no matter which USB port it gets re-plugged.</p>
	<p><i>(It will look like this:</i> <code>/dev/serial/by-id/usb-Arduino_RaspberryPi_Pico_076461E62D414FE3-if00</code>)</p>
	<p> </p>
	<p>[b]Type:[/b] Can be: [Digital in] / [Digital Pullup in] / [Analogue in] / [String]</p>
	<p>[b]Pin:[/b] a number between 0 and the highest GPIO</p>
	<p>[b]Warning:[/b] Analogue pins are counted from 0. (Not the actual GPIO port.) For example RPi-Pico: [0,1,2,3] where 3 is the built-in Temp reader.</p>
    <p> </p>

	<h3>The "in" node:</h3>
	<p>In = Input means: the board which is running firmata is getting data from input pins.</p>
	<p>Then it is sending those data to the host controller, which runs Node-RED.</p>
	<p> </p>
	<p>The sampling interval (frequency), at which data is being collected and sent to host, is set on board's firmata side. If not, default value is: <b>19ms</b> </p>
	<p>The connection between the board(s) and the host can be Wifi, BlueTooth, USB.\n <i>(But the base protocol through those is: Serial port transfer. Default baudRate: 57600 .) Usually: USB port.</i></p>
	<p> </p>

	<h3>Change Log + More info:</h3>
	<p> see: https://github.com/node-red/node-red-nodes/blob/master/hardware/Arduino/README.md </p>
</script>



<script type="text/html" data-template-name="arduino out">
    <div class="form-row">
        <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="node-red:common.label.name"></span></label>
        <input type="text" id="node-input-name" data-i18n="[placeholder]node-red:common.label.name">
    </div>
    <div class="form-row">
        <label for="node-input-arduino"><i class="fa fa-tasks"></i> Arduino</label>
        <input type="text" id="node-input-arduino">
    </div>
    <div class="form-row">
        <label for="node-input-state"><i class="fa fa-wrench"></i> <span data-i18n="arduino.label.type"></span></label>
        <select type="text" id="node-input-state" style="width:200px;">
            <option value="OUTPUT"   data-i18n="arduino.state.out.digital"></option>
            <option value="PWM"      data-i18n="arduino.state.out.analogue"></option>
            <option value="SERVO"    data-i18n="arduino.state.out.servo"></option>
            <option value="STRING"   data-i18n="arduino.state.out.string"></option>
            <option value="RESET"    data-i18n="arduino.state.out.reset"></option>
            <option value="INTERVAL" data-i18n="arduino.state.out.interval"></option>
        </select>
    </div>
    <div class="form-row">
        <label for="node-input-pin"><i class="fa fa-circle"></i> <span data-i18n="arduino.label.pin"></span></label>
        <input type="number" min="0" max="99" id="node-input-pin" style="width:20%;" placeholder="13">
    </div>
    <div class="form-tips"><span data-i18n="[html]arduino.tip.pin"></span></div>
    <div class="form-tips"><span data-i18n="[html]arduino.tip.io"></span></div>
</script>

<script type="text/x-red" data-help-name="arduino out">
	<p>... First read the help at "Arduino in".</p>
	<p>This node's code is at: https://github.com/node-red/node-red-nodes/tree/master/hardware/Arduino </p>
	<p> </p>

    <h3>The "in" node:</h3>
	<p>Out = Output means: you can set individual pins to turn LOW / HIGH / or "x %"=PWM=fast pulses to control voltage.</p>
    <p>You can select:</p><ul>
      <li>- <b>Digital</b> - accepts 0, 1, true, false, on, off</li>
      <li>- <b>Analogue</b> (PWM) - accepts Integer 0 to 255</li>
      <li>- <b>Servo</b> - accepts Integer 0 - 180</li>
      <li>- <b>String</b> - to send a *String* to the Arduino</li>
      <li>- <b>reset</b> - to reset the board, if `msg.payoload = true or 1`</li>
      <li>- <b>Sampling interval</b> - to set a new time (10ms - 65535ms) how fast analogue input data will be transfered</li>
    </ul>
    <p>Digital, PWM, Servo will expects a value in `msg.payload`. </p>
    <p>The pin number must be set in the properties (config) panel before Deploy.</p>
    <p> </p>
    <p>You can also send `msg.payoload = "reset"` to any Output Node without pre-configuring it, to reset the board.</p>
</script>


<script type="text/javascript">
    RED.nodes.registerType('arduino out', {
        category: 'Arduino',
        color:"#3fadb5",
        defaults: {
            name: {value:""},
            pin: {value:"", validate: function(v) {
                    var ct = $("#node-input-state").val() || this.state;
                    return ct === 'STRING' || (v !== '');
                }},
            state: {value:"",required:true},
            arduino: {type:"arduino-board"}
        },
        inputs:1,
        outputs:0,
        icon: "arduino.png",
        align: "right",
        label: function() {
            if (this.state === "STRING") { return "String"; }
            return this.name||"Pin: "+this.pin;
        },
        labelStyle: function() {
            return this.name?"node_label_italic":"";
        }
    });
</script>
